package com.slipper.system.codeless.controller;

import com.slipper.core.tree.TreeInfo;
import com.slipper.core.tree.TreeUtil;
import com.slipper.exception.CommonException;
import com.slipper.system.codeless.bo.DatabaseBO;
import com.slipper.system.codeless.service.DatabaseService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.slipper.system.codeless.bo.DatasourceBO;
import com.slipper.system.codeless.service.DatasourceService;
import com.slipper.constants.Constants;
import com.slipper.util.ResultUtil;
import com.slipper.util.Tool;

import java.sql.DriverManager;
import java.util.List;

/**
 * 数据源信息表
 */
@RestController
@RequestMapping("/system/datasource")
public class DatasourceController {
    @Resource
    private DatabaseService databaseService;
    @Resource
    private DatasourceService datasourceService;
    
    @PostMapping(value = "/queryBy")
    public String queryBy(@RequestBody DatasourceBO bo) {
        if(Tool.isBlank(bo.getId())) {
            return ResultUtil.failureResult("数据获取失败！");
        }
        return ResultUtil.successResult(datasourceService.queryBy(bo.getId()));
    }

    @PostMapping(value = "/queryList")
    public String queryList(@RequestBody DatasourceBO bo) {
        return ResultUtil.successResult(datasourceService.queryList(bo));
    }
    
    @PostMapping(value = "/queryPage")
    public String queryPage(@RequestBody DatasourceBO bo) {
        return ResultUtil.successResult(datasourceService.queryPage(bo));
    }

    @PostMapping(value = "/tree")
    public String queryTree(@RequestBody DatasourceBO bo) {
        List<DatasourceBO> datasourceList = datasourceService.queryList(bo);
        datasourceList.forEach(datasource -> datasource.setDbPassword(null));
        TreeInfo treeInfo = new TreeInfo("数据源树");
        treeInfo.setRootId(Constants.ROOT_ID);
        treeInfo.setIdField("id");
        treeInfo.setTextField("name");
        return ResultUtil.successResult(TreeUtil.buildTree(treeInfo, datasourceList, "asc"));
    }

    @PostMapping(value = "/save")
    public String save(@RequestBody DatasourceBO bo) {
        bo.setDbUrl(parseUrl(bo));
        bo.setOperateId(Constants.getCurrentUser().getEmployeeId());
        return ResultUtil.saveResult(datasourceService.save(bo), bo);
    }

    @PostMapping(value = "/delete")
    public String delete(@RequestBody DatasourceBO bo) {
        return ResultUtil.deleteResult(datasourceService.delete(bo));
    }

    @PostMapping(value = "/connectTest")
    public String connectTest(@RequestBody DatasourceBO bo) {
        try {
            Class.forName(bo.getDbDriver());
            DriverManager.getConnection(parseUrl(bo), bo.getDbUsername(), bo.getDbPassword()).isValid(10000);
            return ResultUtil.successResult("连接成功。");
        } catch (Throwable e) {
            return ResultUtil.failureResult("连接失败：" + e.getLocalizedMessage());
        }
    }

    private String parseUrl(DatasourceBO bo) {
        if (Tool.isBlank(bo.getDatabaseId())) throw new CommonException("数据库类型不能为空！");

        DatabaseBO database = databaseService.queryBy(bo.getDatabaseId());
        if (database == null || Tool.isBlank(database.getUrlTpl())) {
            throw new CommonException("数据库类型地址模板未配置！");
        }
        return database.getUrlTpl()
                .replace("{ip}", bo.getDbIp())
                .replace("{port}", bo.getDbPort() + "")
                .replace("{database}", bo.getDbName())
                .replace("{schema}", Tool.isBlank(bo.getDbSchema()) ? "" : bo.getDbSchema());
    }

    @PostMapping(value = "/queryTablePage")
    public String queryTablePage(@RequestBody DatasourceBO bo) {
        return ResultUtil.successResult(datasourceService.queryTablePage(bo));
    }

    @PostMapping(value = "/queryTableList")
    public String queryTableList(@RequestBody DatasourceBO bo) {
        return ResultUtil.successResult(datasourceService.queryTableList(bo));
    }

    @PostMapping(value = "/queryTableColumnList")
    public String queryTableColumnList(@RequestBody DatasourceBO bo) {
        return ResultUtil.successResult(datasourceService.queryTableColumnList(bo));
    }

    @PostMapping(value = "/queryColumnList")
    public String queryColumnList(@RequestBody DatasourceBO bo) {
        return ResultUtil.successResult(datasourceService.queryColumnList(bo));
    }
}
